#include "./Base/StdAfx.h"
#include "./Base/GameEngine.h"
#include "DrawableTex2D.h"
#include "./Base/DXDevice.h"

DrawableTex2D::DrawableTex2D(): m_Width(0), m_Height(0), m_ColormapFormat(DXGI_FORMAT_UNKNOWN), 
	m_ColorMapSRV(0), m_ColorMapRTV(0), m_DepthMapSRV(0), m_DepthMapDSV(0)
{
	ZeroMemory(&m_ViewPort, sizeof(D3D10_VIEWPORT));
}

DrawableTex2D::~DrawableTex2D()
{
	if(m_ColorMapSRV) m_ColorMapSRV->Release();
	if(m_ColorMapRTV) m_ColorMapRTV->Release();
	if(m_DepthMapDSV) m_DepthMapDSV->Release();
	if(m_DepthMapSRV) m_DepthMapSRV->Release();
}

ID3D10ShaderResourceView* DrawableTex2D::ColorMap() const
{
	return m_ColorMapSRV;
}

ID3D10ShaderResourceView* DrawableTex2D::depthMap() const
{
	return m_DepthMapSRV;
}

void DrawableTex2D::Init(UINT width, UINT height, bool hasColorMap, DXGI_FORMAT colorFormat)
{
	m_Height = height;
	m_Width = width;

	m_ColormapFormat = colorFormat;

	buildDepthMap();

	// Shadows nee no color map
	if(hasColorMap)
		buildColorMap();

	m_ViewPort.TopLeftX = 0;
	m_ViewPort.TopLeftY = 0;
	m_ViewPort.Width = width;
	m_ViewPort.Height = height;
	m_ViewPort.MinDepth = 0.0f;
	m_ViewPort.MaxDepth = 1.0f;
}

void DrawableTex2D::buildDepthMap()
{	
	ID3D10Texture2D* depthMap = 0;
	
	D3D10_TEXTURE2D_DESC texDesc;
	texDesc.Width = m_Width;
	texDesc.Height = m_Height;
	texDesc.MipLevels = 1;
	texDesc.ArraySize = 1;
	texDesc.Format = DXGI_FORMAT_R32_TYPELESS;
	texDesc.SampleDesc.Count = 1;
	texDesc.SampleDesc.Quality = 0;
	texDesc.Usage = D3D10_USAGE_DEFAULT;
	texDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL | D3D10_BIND_SHADER_RESOURCE;
	texDesc.CPUAccessFlags = 0;
	texDesc.MiscFlags = 0;

	HR(DXDEVICE->GetDevice()->CreateTexture2D(&texDesc, 0, &depthMap));

	D3D10_DEPTH_STENCIL_VIEW_DESC dsvDesc;
	dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
	dsvDesc.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
	dsvDesc.Texture2D.MipSlice = 0;
	HR(DXDEVICE->GetDevice()->CreateDepthStencilView(depthMap, &dsvDesc, &m_DepthMapDSV));

	D3D10_SHADER_RESOURCE_VIEW_DESC srvDesc;
	srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
	srvDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
	srvDesc.Texture2D.MipLevels = texDesc.MipLevels;
	srvDesc.Texture2D.MostDetailedMip = 0;
	HR(DXDEVICE->GetDevice()->CreateShaderResourceView(depthMap, &srvDesc, &m_DepthMapSRV));

	depthMap->Release();
}

void DrawableTex2D::buildColorMap()
{
	ID3D10Texture2D* colorMap = 0;

	D3D10_TEXTURE2D_DESC texDesc;
	texDesc.Width = m_Width;
	texDesc.Height = m_Height;
	texDesc.MipLevels = 1;
	texDesc.ArraySize = 1;
	texDesc.Format = m_ColormapFormat;
	texDesc.SampleDesc.Count = 1;
	texDesc.SampleDesc.Quality = 0;
	texDesc.Usage = D3D10_USAGE_DEFAULT;
	texDesc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
	texDesc.CPUAccessFlags = 0;
	texDesc.MiscFlags = D3D10_RESOURCE_MISC_GENERATE_MIPS;

	HR(DXDEVICE->GetDevice()->CreateTexture2D(&texDesc, 0, &colorMap));

	HR(DXDEVICE->GetDevice()->CreateRenderTargetView(colorMap, 0, &m_ColorMapRTV));
	HR(DXDEVICE->GetDevice()->CreateShaderResourceView(colorMap, 0, &m_ColorMapSRV));

	colorMap->Release();
}

void DrawableTex2D::begin()
{
	ID3D10RenderTargetView* renderTargets[1] = {m_ColorMapRTV};
	DXDEVICE->GetDevice()->OMSetRenderTargets(1, renderTargets, m_DepthMapDSV);
	DXDEVICE->GetDevice()->RSSetViewports(1, &m_ViewPort);

	float clearcolor[4] = {0.0f, 0.0f, 0.0f, 1.0f};
	if(m_ColorMapRTV)
		DXDEVICE->GetDevice()->ClearRenderTargetView(m_ColorMapRTV, clearcolor);

	DXDEVICE->GetDevice()->ClearDepthStencilView(m_DepthMapDSV, D3D10_CLEAR_DEPTH, 1.0f, 0);
}

void DrawableTex2D::end()
{
	if(m_ColorMapSRV)
		DXDEVICE->GetDevice()->GenerateMips(m_ColorMapSRV);
	DXDEVICE->ResetRenderTargets();
}

void DrawableTex2D::SaveDepth( const tstring& file )
{
	ID3D10Resource* res;
	m_DepthMapSRV->GetResource(&res);
	D3DX10SaveTextureToFile(res, D3DX10_IFF_DDS, file.c_str());
	res->Release();
	LOG(_T("Depth map opgeslagen."));
}

void DrawableTex2D::SaveColor( const tstring& file )
{
	ID3D10Resource* res;
	m_ColorMapSRV->GetResource(&res);
	D3DX10SaveTextureToFile(res, D3DX10_IFF_DDS, file.c_str());
	res->Release();
	LOG(_T("Color map opgeslagen."));
}